import { BaseEntity } from './BaseEntity';
import { UserLevel } from '../../shared/face';

/**
 * 玩家实体类
 */
export class Player extends BaseEntity {
    /** 玩家名称 */
    public name: string;
    
    /** 用户级别 */
    public userLevel: UserLevel;
    
    /** 角色等级 */
    public level: number;
    
    /** 当前经验值 */
    public experience: number;
    
    /** 升级所需经验值 */
    public maxExperience: number;
    
    /** 可用属性点 */
    public attributePoints: number;
    
    /** 可用技能点 */
    public skillPoints: number;
    
    /** 基础属性 */
    public attributes: PlayerAttributes;
    
    /** 当前状态 */
    public currentStats: PlayerStats;
    
    /** 最大状态 */
    public maxStats: PlayerStats;
    
    /** 背包物品 */
    public bagItems: any[];
    
    /** 背包最大容量 */
    public bagMaxSize: number;
    
    /** 已学技能 */
    public skills: any[];
    
    /** 装备物品 */
    public equipment: PlayerEquipment;
    
    /** 玩家状态 */
    public state: PlayerState;
    
    /** 位置信息 */
    public position: PlayerPosition;
    
    /** 任务进度 */
    public taskProgress: Record<string, any>;
    
    /** 成就数据 */
    public achievements: string[];
    
    /** 最后登录时间 */
    public lastLoginAt?: Date;
    
    /** 总在线时间（毫秒） */
    public totalOnlineTime: number;
    
    /** 玩家设置 */
    public settings: PlayerSettings;

    constructor(id?: string) {
        super(id);
        
        // 设置默认值
        this.name = '未命名';
        this.userLevel = UserLevel.玩家;
        this.level = 1;
        this.experience = 0;
        this.maxExperience = 100;
        this.attributePoints = 5;
        this.skillPoints = 1;
        
        // 初始化属性
        this.attributes = {
            strength: 10,     // 力量
            agility: 10,      // 敏捷
            intelligence: 10, // 智力
            constitution: 10, // 体质
            spirit: 10,       // 精神
        };
        
        // 初始化状态
        this.currentStats = {
            hp: 100,
            mp: 50,
            attack: 15,
            defense: 10,
            speed: 10,
            criticalRate: 0.05,
            criticalDamage: 1.5,
        };
        
        this.maxStats = { ...this.currentStats };
        
        // 初始化容器
        this.bagItems = [];
        this.bagMaxSize = 100;
        this.skills = [];
        this.achievements = [];
        this.taskProgress = {};
        
        // 初始化装备
        this.equipment = {
            weapon: null,
            helmet: null,
            armor: null,
            pants: null,
            shoes: null,
            accessory: null,
        };
        
        // 初始化状态
        this.state = PlayerState.IDLE;
        
        // 初始化位置
        this.position = {
            scene: 'default',
            x: 0,
            y: 0,
            z: 0,
        };
        
        // 初始化时间
        this.totalOnlineTime = 0;
        
        // 初始化设置
        this.settings = {
            autoPickup: true,
            showDamage: true,
            soundEnabled: true,
            musicEnabled: true,
        };
    }

    /**
     * 添加经验值
     */
    public addExperience(amount: number): LevelUpResult {
        if (amount <= 0) {
            throw new Error('经验值必须大于0');
        }

        this.experience += amount;
        let levelUps = 0;
        
        // 检查是否升级
        while (this.experience >= this.maxExperience && this.level < 100) {
            this.experience -= this.maxExperience;
            this.level += 1;
            levelUps += 1;
            
            // 计算下一级所需经验
            this.maxExperience = Math.floor(100 * Math.pow(1.2, this.level - 1));
            
            // 升级奖励
            this.attributePoints += 5;
            this.skillPoints += 1;
            
            // 恢复状态
            this.currentStats.hp = this.maxStats.hp;
            this.currentStats.mp = this.maxStats.mp;
        }

        this.updateEntity();
        
        return {
            leveledUp: levelUps > 0,
            levelsGained: levelUps,
            newLevel: this.level,
            newExperience: this.experience,
            maxExperience: this.maxExperience,
        };
    }

    /**
     * 分配属性点
     */
    public allocateAttributePoint(attribute: keyof PlayerAttributes, points: number): void {
        if (points <= 0 || points > this.attributePoints) {
            throw new Error('属性点分配数量无效');
        }

        this.attributes[attribute] += points;
        this.attributePoints -= points;
        
        // 重新计算战斗属性
        this.recalculateStats();
        this.updateEntity();
    }

    /**
     * 学习技能
     */
    public learnSkill(skill: any): void {
        if (this.skillPoints <= 0) {
            throw new Error('技能点不足');
        }

        // 检查是否已学习
        const existingSkill = this.skills.find(s => s.id === skill.id);
        if (existingSkill) {
            throw new Error('技能已学习');
        }

        this.skills.push(skill);
        this.skillPoints -= 1;
        this.updateEntity();
    }

    /**
     * 装备物品
     */
    public equipItem(equipment: any): any | null {
        const slot = equipment.slotType as keyof PlayerEquipment;
        const oldEquipment = this.equipment[slot];
        
        this.equipment[slot] = equipment;
        
        // 重新计算属性
        this.recalculateStats();
        this.updateEntity();
        
        return oldEquipment;
    }

    /**
     * 卸下装备
     */
    public unequipItem(slot: keyof PlayerEquipment): any | null {
        const equipment = this.equipment[slot];
        this.equipment[slot] = null;
        
        // 重新计算属性
        this.recalculateStats();
        this.updateEntity();
        
        return equipment;
    }

    /**
     * 重新计算战斗属性
     */
    private recalculateStats(): void {
        // 基础属性影响
        const baseHp = 100 + this.attributes.constitution * 10;
        const baseMp = 50 + this.attributes.intelligence * 5;
        const baseAttack = 10 + this.attributes.strength * 2;
        const baseDefense = 5 + this.attributes.constitution * 1;
        const baseSpeed = 10 + this.attributes.agility * 1;
        
        // 装备加成
        let equipmentBonus = {
            hp: 0,
            mp: 0,
            attack: 0,
            defense: 0,
            speed: 0,
            criticalRate: 0,
            criticalDamage: 0,
        };

        Object.values(this.equipment).forEach(equipment => {
            if (equipment && equipment.attributes) {
                equipment.attributes.forEach((attr: any) => {
                    if (attr.key in equipmentBonus) {
                        equipmentBonus[attr.key as keyof typeof equipmentBonus] += attr.value;
                    }
                });
            }
        });

        // 更新最大属性
        this.maxStats = {
            hp: baseHp + equipmentBonus.hp,
            mp: baseMp + equipmentBonus.mp,
            attack: baseAttack + equipmentBonus.attack,
            defense: baseDefense + equipmentBonus.defense,
            speed: baseSpeed + equipmentBonus.speed,
            criticalRate: 0.05 + equipmentBonus.criticalRate,
            criticalDamage: 1.5 + equipmentBonus.criticalDamage,
        };

        // 当前血量和蓝量不超过最大值
        this.currentStats.hp = Math.min(this.currentStats.hp, this.maxStats.hp);
        this.currentStats.mp = Math.min(this.currentStats.mp, this.maxStats.mp);
        
        // 更新其他属性
        this.currentStats.attack = this.maxStats.attack;
        this.currentStats.defense = this.maxStats.defense;
        this.currentStats.speed = this.maxStats.speed;
        this.currentStats.criticalRate = this.maxStats.criticalRate;
        this.currentStats.criticalDamage = this.maxStats.criticalDamage;
    }

    /**
     * 恢复生命值
     */
    public healHp(amount: number): void {
        this.currentStats.hp = Math.min(this.currentStats.hp + amount, this.maxStats.hp);
        this.updateEntity();
    }

    /**
     * 恢复魔法值
     */
    public restoreMp(amount: number): void {
        this.currentStats.mp = Math.min(this.currentStats.mp + amount, this.maxStats.mp);
        this.updateEntity();
    }

    /**
     * 受到伤害
     */
    public takeDamage(damage: number): boolean {
        const actualDamage = Math.max(1, damage - this.currentStats.defense);
        this.currentStats.hp = Math.max(0, this.currentStats.hp - actualDamage);
        
        if (this.currentStats.hp <= 0) {
            this.state = PlayerState.DEAD;
        }
        
        this.updateEntity();
        return this.currentStats.hp <= 0;
    }

    /**
     * 复活
     */
    public revive(): void {
        this.currentStats.hp = Math.floor(this.maxStats.hp * 0.5);
        this.currentStats.mp = Math.floor(this.maxStats.mp * 0.5);
        this.state = PlayerState.IDLE;
        this.updateEntity();
    }

    /**
     * 验证玩家数据
     */
    public validate(): any {
        const result = super.validate();
        
        if (!this.name || this.name.trim().length === 0) {
            result.errors.push({ field: 'name', message: '玩家名称不能为空' });
        }
        
        if (this.level < 1 || this.level > 100) {
            result.errors.push({ field: 'level', message: '玩家等级必须在1-100之间' });
        }
        
        if (this.experience < 0) {
            result.errors.push({ field: 'experience', message: '经验值不能为负数' });
        }
        
        result.isValid = result.errors.length === 0;
        return result;
    }
}

/**
 * 玩家属性接口
 */
export interface PlayerAttributes {
    strength: number;      // 力量
    agility: number;       // 敏捷
    intelligence: number;  // 智力
    constitution: number;  // 体质
    spirit: number;        // 精神
}

/**
 * 玩家状态接口
 */
export interface PlayerStats {
    hp: number;              // 生命值
    mp: number;              // 魔法值
    attack: number;          // 攻击力
    defense: number;         // 防御力
    speed: number;           // 速度
    criticalRate: number;    // 暴击率
    criticalDamage: number;  // 暴击伤害
}

/**
 * 玩家装备接口
 */
export interface PlayerEquipment {
    weapon: any | null;     // 武器
    helmet: any | null;     // 头盔
    armor: any | null;      // 护甲
    pants: any | null;      // 裤子
    shoes: any | null;      // 鞋子
    accessory: any | null;  // 饰品
}

/**
 * 玩家状态枚举
 */
export enum PlayerState {
    IDLE = 'idle',           // 空闲
    MOVING = 'moving',       // 移动中
    FIGHTING = 'fighting',   // 战斗中
    DEAD = 'dead',          // 死亡
    TRADING = 'trading',    // 交易中
    OFFLINE = 'offline',    // 离线
}

/**
 * 玩家位置接口
 */
export interface PlayerPosition {
    scene: string;  // 场景ID
    x: number;      // X坐标
    y: number;      // Y坐标
    z: number;      // Z坐标
}

/**
 * 玩家设置接口
 */
export interface PlayerSettings {
    autoPickup: boolean;    // 自动拾取
    showDamage: boolean;    // 显示伤害
    soundEnabled: boolean;  // 音效开启
    musicEnabled: boolean;  // 音乐开启
}

/**
 * 升级结果接口
 */
export interface LevelUpResult {
    leveledUp: boolean;     // 是否升级
    levelsGained: number;   // 升级数量
    newLevel: number;       // 新等级
    newExperience: number;  // 新经验值
    maxExperience: number;  // 最大经验值
}
